home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / UTILITIE / CONVERSI / 3760.ZIP / APL2EM.ZIP / CGA.ASM < prev    next >
Assembly Source File  |  1990-03-30  |  50KB  |  1,311 lines

  1.     Page    58,132
  2.     Title    CGA.ASM     Apple CGA Video Routines
  3. ;******************************************************************************
  4. ;
  5. ;   Name:    CGA.ASM     Apple CGA Video Routines
  6. ;
  7. ;   Group:    Emulator
  8. ;
  9. ;   Revision:    1.00
  10. ;
  11. ;   Date:    January 30, 1988
  12. ;
  13. ;   Author:    Randy W. Spurlock
  14. ;
  15. ;******************************************************************************
  16. ;
  17. ;  Module Functional Description:
  18. ;
  19. ;        This module contains all the code for the Apple
  20. ;    CGA video routines.
  21. ;
  22. ;******************************************************************************
  23. ;
  24. ;  Changes:
  25. ;
  26. ;    DATE     REVISION                DESCRIPTION
  27. ;  --------   --------    -------------------------------------------------------
  28. ;   1/30/88    1.00    Original
  29. ;
  30. ;******************************************************************************
  31.     Page
  32. ;
  33. ;  Public Declarations
  34. ;
  35.     Public    CGA_Text_1        ; Low resolution/text page 1 write
  36.     Public    CGA_Text_2        ; Low resolution/text page 2 write
  37.     Public    CGA_Graph_1        ; High resolution page 1 write
  38.     Public    CGA_Graph_2        ; High resolution page 2 write
  39.     Public    CGA_Text_Off        ; Text mode off (Graphics)
  40.     Public    CGA_Text_On        ; Text mode on (Text)
  41.     Public    CGA_Mixed_Off        ; Mixed off (Text / Graphics)
  42.     Public    CGA_Mixed_On        ; Mixed on (Text & Graphics)
  43.     Public    CGA_Page_1        ; Select video page 1 (Text & Graphics)
  44.     Public    CGA_Page_2        ; Select video page 2 (Text & Graphics)
  45.     Public    CGA_Low_Res        ; Select low resolution (Graphics)
  46.     Public    CGA_High_Res        ; Select high resolution (Graphics)
  47.     Public    CGA_Restore        ; CGA restore screen routine
  48. ;
  49. ;  External Declarations
  50. ;
  51.     Extrn    Cursor_Off:Near     ; Turn cursor off routine    (VIDEO)
  52.     Extrn    Cursor_On:Near        ; Turn cursor on routine    (VIDEO)
  53.     Extrn    Blink_Off:Near        ; Turn blink off routine    (VIDEO)
  54.     Extrn    Blink_On:Near        ; Turn blink on routine     (VIDEO)
  55.     Extrn    Set_Address:Near    ; Set video address routine    (VIDEO)
  56.     Extrn    Text_Address:Word    ; Text address mapping table    (VIDEO)
  57.     Extrn    Macro_Table:Word    ; Text macro table        (VIDEO)
  58.     Extrn    Char_Table:Word     ; Text character mapping table    (VIDEO)
  59.     Extrn    CGA_Address:Word    ; CGA graphics address table    (VIDEO)
  60.     Extrn    CGA_Slice:Word        ; CGA graphics macro/slice table(VIDEO)
  61.     Extrn    Reverse_Table:Byte    ; Bit reversal table        (VIDEO)
  62.     Extrn    Even_Table:Word     ; Even column bit exp. table    (VIDEO)
  63.     Extrn    Odd_Table:Word        ; Odd column bit exp. table    (VIDEO)
  64.     Extrn    Column_Table:Word    ; Column exp. selection table    (VIDEO)
  65.     Extrn    CGA_Shift:Byte        ; CGA bit shift table        (VIDEO)
  66.     Extrn    Map_Table:Byte        ; Low res. color mapping table    (VIDEO)
  67.     Extrn    Video_Flag:Byte     ; Video system flag byte     (DATA)
  68. ;
  69. ;  LOCAL Equates
  70. ;
  71. TEXT_PAGE_1    Equ    04h        ; Starting text page 1 page value
  72. TEXT_PAGE_2    Equ    08h        ; Starting text page 2 page value
  73. GRAPH_PAGE_1    Equ    20h        ; Starting graphics page 1 page value
  74. GRAPH_PAGE_2    Equ    40h        ; Starting graphics page 2 page value
  75. TEXT_ADDRESS_1    Equ    0400h        ; Starting text page 1 address value
  76. TEXT_ADDRESS_2    Equ    0800h        ; Starting text page 2 address value
  77. GRAPH_ADDRESS_1 Equ    2000h        ; Starting graphics page 1 address value
  78. GRAPH_ADDRESS_2 Equ    4000h        ; Starting graphics page 2 address value
  79. BASE_ADDRESS    Equ    0000h        ; Base video memory address
  80. BLOCK_CHAR    Equ    0DFh        ; Low resolution block character value
  81. SLICE_COUNT    Equ    08h        ; Slice count value (8 = 192 Lines)
  82. MACRO_COUNT    Equ    08h        ; Macro count value (8 = 24 Rows)
  83. ROW_COUNT    Equ    03h        ; Row count value (3 = 3 Rows)
  84. CHAR_COUNT    Equ    28h        ; Character column count (40 Bytes)
  85. BYTE_COUNT    Equ    0Ah        ; Graphics byte count (10 = 40 Bytes)
  86. MACRO_OFFSET    Equ    08h        ; Macro offset value (Screen holes [8])
  87. NEXT_OFFSET    Equ    50h        ; Next row offset value (80)
  88. ROW_OFFSET    Equ    0230h        ; Row offset value (7 * 40 * 2)
  89. NEXT_MACRO    Equ    0140h        ; Next macro set offset value (Graphics)
  90. NEXT_ROW    Equ    09BAh        ; Next row offset value (Graphics)
  91. LINE_MASK    Equ    2000h        ; Next line XOR mask value
  92. TEXT_MASK    Equ    07FFh        ; Text destination mask value
  93. TEXT_MODE    Equ    00h        ; Text mode value (40 x 25)
  94. GRAPH_MODE    Equ    04h        ; Graphics mode value (320 x 200)
  95. COLOR_MASK    Equ    007Fh        ; Color bit mask value
  96. WORD_MASK    Equ    0FFFCh        ; Word mask initial value
  97. BYTE_MASK    Equ    0FCh        ; Byte mask initial value
  98. ADDRESS_MASK    Equ    03h        ; Address bits mask value (Mod 4)
  99. ODD_COLUMN    Equ    0001h        ; Odd column test mask value
  100. BYTE_OFFSET    Equ    02h        ; Byte offset value
  101. ;
  102. ;  Define any include files needed
  103. ;
  104.     Include     Macros.inc    ; Include the macro definitions
  105.     Include     Equates.inc    ; Include the equate definitions
  106.     .286c                ; Include 80286 instructions
  107.     Page
  108. ;
  109. ;  Define the emulator code segment
  110. ;
  111. Emulate Segment Word Public 'EMULATE'   ; Emulator code segment
  112.     Assume    cs:Emulate, ds:Nothing, es:Nothing
  113.     Subttl    CGA_Text_1    Low Resolution/Text Page 1 Write
  114.     Page    +
  115. ;******************************************************************************
  116. ;
  117. ;    CGA_Text_1(Effective_Address, Value)
  118. ;
  119. ;        Write the memory location value (Byte)
  120. ;        If this is a text mode and page 1
  121. ;            Save the required registers
  122. ;            Save the character table index value
  123. ;            Set base text video address
  124. ;            Calculate macro line and offset values
  125. ;            Load offset value from offset table
  126. ;            If this is NOT a screen hole
  127. ;                Load macro line value from macro table
  128. ;                Compute the actual screen address
  129. ;                Lookup the character/attribute values
  130. ;                Store the character to the screen
  131. ;            Endif this is a screen hole
  132. ;            Restore the required registers
  133. ;        Else this is a graphics mode
  134. ;            If this is low resolution graphics mode page 1
  135. ;                Save the required registers
  136. ;                Save the graphics byte index value
  137. ;                Set base text video address
  138. ;                Calculate macro line and offset values
  139. ;                Load offset value from offset table
  140. ;                If this is NOT a screen hole
  141. ;                    Load macro line value from macro table
  142. ;                    Compute the actual screen address
  143. ;                    Lookup the graphics mapping value
  144. ;                    Force character code to a half block
  145. ;                    Store the character to the screen
  146. ;                Endif this is a screen hole
  147. ;                Restore the required registers
  148. ;        Endif for mode value
  149. ;        Return to the caller
  150. ;
  151. ;    Registers on Entry:
  152. ;
  153. ;        AL    - Memory value
  154. ;        DS:DI - 65C02 Effective address
  155. ;        ES    - Video memory segment
  156. ;
  157. ;    Registers on Exit:
  158. ;
  159. ;        AX    - Destroyed
  160. ;        DI    - Destroyed
  161. ;        BP    - Destroyed
  162. ;
  163. ;******************************************************************************
  164.         Even            ; Force procedure to even address
  165. CGA_Text_1    Proc    Near        ; Low res/text page 1 write procedure
  166.     mov    ds:[di],al        ; Write the memory location
  167.     test    cs:[Video_Flag],VIDEO_MODE+PAGE_NUMBER
  168.     jnz    Low_Check_1        ; Jump if NOT text mode page 1
  169.     Save    bx            ; Save the required registers
  170.     xor    ah,ah            ; Convert character to full word
  171.     shl    ax,1            ; Convert character to table index
  172.     mov    bp,ax            ; Save character table index in BP
  173.     mov    ax,di            ; Get the effective memory address
  174.     sub    ah,TEXT_PAGE_1        ; Subtract off the starting value
  175.     shl    ax,1            ; Move macro number into AH register
  176.     xor    bh,bh            ; Setup to index through video tables
  177.     mov    bl,al            ; Convert offset into table index
  178.     mov    di,cs:[bx+Text_Address] ; Get the text offset table value
  179.     inc    di            ; Increment for screen hole check
  180.     js    Text_1_Hole        ; Jump if this is a screen hole
  181.     mov    bl,ah            ; Get macro number into BL register
  182.     shl    bx,1            ; Convert macro number into table index
  183.     add    di,cs:[bx+Macro_Table]    ; Compute the actual screen address
  184.     mov    ax,cs:[bp+Char_Table]    ; Lookup the correct character value
  185.     stosw                ; Store character value onto screen
  186. Text_1_Hole:
  187.     Restore bx            ; Restore the required registers
  188. Text_Done_1:
  189.     ret                ; Return to the caller
  190. Low_Check_1:
  191.     test    cs:[Video_Flag],RESOLUTION+PAGE_NUMBER
  192.     jnz    Low_Done_1        ; Jump if NOT low resolution page 1
  193.     Save    bx            ; Save the required registers
  194.     mov    ah,al            ; Move graphics byte to AH register
  195.     mov    bp,ax            ; Save graphices byte value in BP
  196.     mov    ax,di            ; Get the effective memory address
  197.     sub    ah,TEXT_PAGE_1        ; Subtract off the starting value
  198.     shl    ax,1            ; Move macro number in AH register
  199.     xor    bh,bh            ; Setup to index through video tables
  200.     mov    bl,al            ; Convert offset into table index
  201.     mov    di,cs:[bx+Text_Address] ; Get the text offset table value
  202.     inc    di            ; Increment for screen hole check
  203.     js    Low_1_Hole        ; Jump if this is a screen hole
  204.     mov    bl,ah            ; Get macro number into BL register
  205.     shl    bx,1            ; Convert macro number into table index
  206.     add    di,cs:[bx+Macro_Table]    ; Compute the actual screen offset
  207.     mov    ax,bp            ; Restore the graphics byte value
  208.     mov    al,BLOCK_CHAR        ; Force character to block character
  209.     stosw                ; Store graphics value onto screen
  210. Low_1_Hole:
  211.     Restore bx            ; Restore the required registers
  212. Low_Done_1:
  213.     ret                ; Return to the caller
  214. CGA_Text_1    Endp            ; End of the CGA_Text_1 procedure
  215.     Subttl    CGA_Text_2    Low Resolution/Text Page 2 Write
  216.     Page    +
  217. ;******************************************************************************
  218. ;
  219. ;    CGA_Text_2(Effective_Address, Value)
  220. ;
  221. ;        Write the memory location value (Byte)
  222. ;        If this is a text mode and page 2
  223. ;            Save the required registers
  224. ;            Save the character table index value
  225. ;            Set base text video address
  226. ;            Calculate macro line and offset values
  227. ;            Load offset value from offset table
  228. ;            If this is NOT a screen hole
  229. ;                Load macro line value from macro table
  230. ;                Compute the actual screen address
  231. ;                Lookup the character/attribute values
  232. ;                Store the character to the screen
  233. ;            Endif this is a screen hole
  234. ;            Restore the required registers
  235. ;        Else this is a graphics mode
  236. ;            If this is low resolution graphics mode page 2
  237. ;                Save the required registers
  238. ;                Save the graphics byte index value
  239. ;                Set base text video address
  240. ;                Calculate macro line and offset values
  241. ;                Load offset value from offset table
  242. ;                If this is NOT a screen hole
  243. ;                    Load macro line value from macro table
  244. ;                    Compute the actual screen address
  245. ;                    Lookup the graphics mapping value
  246. ;                    Force character code to a half block
  247. ;                    Store the character to the screen
  248. ;                Endif this is a screen hole
  249. ;                Restore the required registers
  250. ;        Endif for mode value
  251. ;        Return to the caller
  252. ;
  253. ;    Registers on Entry:
  254. ;
  255. ;        AL    - Memory value
  256. ;        DS:DI - 65C02 Effective address
  257. ;        ES    - Video memory segment
  258. ;
  259. ;    Registers on Exit:
  260. ;
  261. ;        AX    - Destroyed
  262. ;        DI    - Destroyed
  263. ;        BP    - Destroyed
  264. ;
  265. ;******************************************************************************
  266.         Even            ; Force procedure to even address
  267. CGA_Text_2    Proc    Near        ; Low res/text page 2 write procedure
  268.     mov    ds:[di],al        ; Write the memory location
  269.     test    cs:[Video_Flag],VIDEO_MODE+PAGE_INV
  270.     jnz    Low_Check_2        ; Jump if NOT text mode page 2
  271.     Save    bx            ; Save the required registers
  272.     xor    ah,ah            ; Convert character to full word
  273.     shl    ax,1            ; Convert character to table index
  274.     mov    bp,ax            ; Save character table index in BP
  275.     mov    ax,di            ; Get the effective memory address
  276.     sub    ah,TEXT_PAGE_2        ; Subtract off the starting value
  277.     shl    ax,1            ; Move macro number into AH register
  278.     xor    bh,bh            ; Setup to index through video tables
  279.     mov    bl,al            ; Convert offset into table index
  280.     mov    di,cs:[bx+Text_Address] ; Get the text offset table value
  281.     inc    di            ; Increment for screen hole check
  282.     js    Text_2_Hole        ; Jump if this is a screen hole
  283.     mov    bl,ah            ; Get macro number into BL register
  284.     shl    bx,1            ; Convert macro number into table index
  285.     add    di,cs:[bx+Macro_Table]    ; Compute the actual screen address
  286.     mov    ax,cs:[bp+Char_Table]    ; Lookup the correct character value
  287.     stosw                ; Store character value onto screen
  288. Text_2_Hole:
  289.     Restore bx            ; Restore the required registers
  290. Text_Done_2:
  291.     ret                ; Return to the caller
  292. Low_Check_2:
  293.     test    cs:[Video_Flag],RESOLUTION+PAGE_INV
  294.     jnz    Low_Done_2        ; Jump if NOT low resolution page 2
  295.     Save    bx            ; Save the required registers
  296.     mov    ah,al            ; Move graphics byte to AH register
  297.     mov    bp,ax            ; Save graphices byte value in BP
  298.     mov    ax,di            ; Get the effective memory address
  299.     sub    ah,TEXT_PAGE_2        ; Subtract off the starting value
  300.     shl    ax,1            ; Move macro number in AH register
  301.     xor    bh,bh            ; Setup to index through video tables
  302.     mov    bl,al            ; Convert offset into table index
  303.     mov    di,cs:[bx+Text_Address] ; Get the text offset table value
  304.     inc    di            ; Increment for screen hole check
  305.     js    Low_2_Hole        ; Jump if this is a screen hole
  306.     mov    bl,ah            ; Get macro number into BL register
  307.     shl    bx,1            ; Convert macro number into table index
  308.     add    di,cs:[bx+Macro_Table]    ; Compute the actual screen offset
  309.     mov    ax,bp            ; Restore the graphics byte value
  310.     mov    al,BLOCK_CHAR        ; Force character to block character
  311.     stosw                ; Store graphics value onto screen
  312. Low_2_Hole:
  313.     Restore bx            ; Restore the required registers
  314. Low_Done_2:
  315.     ret                ; Return to the caller
  316. CGA_Text_2    Endp            ; End of the CGA_Text_2 procedure
  317.     Subttl    CGA_Graph_1    High Resolution Graphics Page 1 Write
  318.     Page    +
  319. ;******************************************************************************
  320. ;
  321. ;    CGA_Graph_1(Effective_Address, Value)
  322. ;
  323. ;        Write the memory location value (Byte)
  324. ;        If this is a graphics mode and page 1
  325. ;            Save the required registers
  326. ;            Save the bit value table index value
  327. ;            Calculate macro/slice and offset values
  328. ;            Load offset value from offset table
  329. ;            If this is NOT a screen hole
  330. ;                Load macro/slice value from macro/slice table
  331. ;                Compute the actual screen address
  332. ;                Lookup the reverse bit value
  333. ;                Lookup the expanded bit value
  334. ;                Get the word/byte shift count values
  335. ;                Get the word mask value
  336. ;                Shift the word mask into position
  337. ;                Shift the expanded bits into position
  338. ;                Update the screen word value
  339. ;                If the byte shift count is NOT zero
  340. ;                    Get the byte mask value
  341. ;                    Shift byte mask into position
  342. ;                    Shift expanded bits into position
  343. ;                    Update the screen byte value
  344. ;                Endif
  345. ;            Endif this is a screen hole
  346. ;            Restore the required registers
  347. ;        Endif this is NOT a graphics mode
  348. ;        Return to the caller
  349. ;
  350. ;    Registers on Entry:
  351. ;
  352. ;        AL    - Memory value
  353. ;        DS:DI - 65C02 Effective address
  354. ;        ES    - Video memory segment
  355. ;
  356. ;    Registers on Exit:
  357. ;
  358. ;        AX    - Destroyed
  359. ;        DI    - Destroyed
  360. ;        BP    - Destroyed
  361. ;
  362. ;******************************************************************************
  363.         Even            ; Force procedure to even address
  364. CGA_Graph_1    Proc    Near        ; High res page 1 write procedure
  365.     mov    ds:[di],al        ; Write the memory location
  366.     test    cs:[Video_Flag],VIDEO_INV+PAGE_NUMBER+RES_INV
  367.     jnz    Graph_Done_1        ; Jump if NOT high res. mode page 1
  368.     Save    bx,cx,dx,si        ; Save the required registers
  369.     and    ax,COLOR_MASK        ; Mask off all but the color bits
  370.     mov    bp,ax            ; Save bit value table index in BP
  371.     mov    ax,di            ; Get the effective memory address
  372.     and    di,ADDRESS_MASK     ; Mask all but required address bits
  373.     sub    ah,GRAPH_PAGE_1     ; Subtract off the starting value
  374.     shl    ax,1            ; Move macro/slice number to AH register
  375.     xor    bh,bh            ; Setup to index through video tables
  376.     mov    bl,al            ; Convert offset into table index
  377.     mov    si,cs:[bx+CGA_Address]    ; Get the graphics offset table value
  378.     inc    si            ; Increment for screen hole check
  379.     js    Graph_Exit_1        ; Jump if this is a screen hole
  380.     mov    bl,ah            ; Get macro/slice number to BL register
  381.     shl    bx,1            ; Convert macro/slice into table index
  382.     add    si,cs:[bx+CGA_Slice]    ; Compute the actual screen address
  383.     mov    ch,cs:[di+CGA_Shift]    ; Get the word/byte shift values
  384.     mov    bl,cs:[bp+Reverse_Table]; Lookup the reverse bit value
  385.     shl    di,1            ; Convert address into table index
  386.     add    bx,cs:[di+Column_Table] ; Compute the actual table entry address
  387.     mov    dx,Word Ptr cs:[bx]    ; Get the expanded bit value (14 Bits)
  388.     mov    bx,dx            ; Get a copy of expanded bit value
  389.     mov    ax,WORD_MASK        ; Get the word mask value
  390.     xor    cl,cl            ; Setup for word shift count
  391.     rol    cx,4            ; Shift word shift count into CL
  392.     shr    ax,cl            ; Shift mask value into position
  393.     shr    bx,cl            ; Shift data value into position
  394.     not    ax            ; Invert the mask polarity
  395.     xchg    al,ah            ; Put mask bytes into the correct order
  396.     xchg    bl,bh            ; Put data bytes into the correct order
  397.     and    ax,Word Ptr es:[si]    ; Mask off all but desired bits
  398.     or    ax,bx            ; Logically OR in the new data bits
  399.     mov    Word Ptr es:[si],ax    ; Update the screen data word value
  400.     xor    cl,cl            ; Setup for byte shift count
  401.     rol    cx,4            ; Shift byte shift count into CL
  402.     or    cl,cl            ; Check for byte value required
  403.     jz    Graph_Exit_1        ; Jump if byte value NOT required
  404.     mov    al,BYTE_MASK        ; Get the byte mask value
  405.     shl    al,cl            ; Shift mask value into position
  406.     shl    dl,cl            ; Shift data value into position
  407.     not    al            ; Invert the mask polarity
  408.     and    al,Byte Ptr es:[si+BYTE_OFFSET]
  409.     or    al,dl            ; Logically OR in the new data bits
  410.     mov    Byte Ptr es:[si+BYTE_OFFSET],al
  411. Graph_Exit_1:
  412.     Restore bx,cx,dx,si        ; Restore the required registers
  413. Graph_Done_1:
  414.     ret                ; Return to the caller
  415. CGA_Graph_1    Endp            ; End of the CGA_Graph_1 procedure
  416.     Subttl    CGA_Graph_2    High Resolution Graphics Page 2 Write
  417.     Page    +
  418. ;******************************************************************************
  419. ;
  420. ;    CGA_Graph_2(Effective_Address, Value)
  421. ;
  422. ;        Write the memory location value (Byte)
  423. ;        If this is a graphics mode and page 2
  424. ;            Save the required registers
  425. ;            Save the bit value table index value
  426. ;            Calculate macro/slice and offset values
  427. ;            Load offset value from offset table
  428. ;            If this is NOT a screen hole
  429. ;                Load macro/slice value from macro/slice table
  430. ;                Compute the actual screen address
  431. ;                Lookup the reverse bit value
  432. ;                Lookup the expanded bit value
  433. ;                Get the word/byte shift count values
  434. ;                Get the word mask value
  435. ;                Shift the word mask into position
  436. ;                Shift the expanded bits into position
  437. ;                Update the screen word value
  438. ;                If the byte shift count is NOT zero
  439. ;                    Get the byte mask value
  440. ;                    Shift byte mask into position
  441. ;                    Shift expanded bits into position
  442. ;                    Update the screen byte value
  443. ;                Endif
  444. ;            Endif this is a screen hole
  445. ;            Restore the required registers
  446. ;        Endif this is NOT a graphics mode
  447. ;        Return to the caller
  448. ;
  449. ;    Registers on Entry:
  450. ;
  451. ;        AL    - Memory value
  452. ;        DS:DI - 65C02 Effective address
  453. ;        ES    - Video memory segment
  454. ;
  455. ;    Registers on Exit:
  456. ;
  457. ;        AX    - Destroyed
  458. ;        DI    - Destroyed
  459. ;        BP    - Destroyed
  460. ;
  461. ;******************************************************************************
  462.         Even            ; Force procedure to even address
  463. CGA_Graph_2    Proc    Near        ; High res page 2 write procedure
  464.     mov    ds:[di],al        ; Write the memory location
  465.     test    cs:[Video_Flag],VIDEO_INV+PAGE_INV+RES_INV
  466.     jnz    Graph_Done_2        ; Jump if NOT high res. mode page 2
  467.     Save    bx,cx,dx,si        ; Save the required registers
  468.     and    ax,COLOR_MASK        ; Mask off all but the color bits
  469.     mov    bp,ax            ; Save bit value table index in BP
  470.     mov    ax,di            ; Get the effective memory address
  471.     and    di,ADDRESS_MASK     ; Mask all but required address bits
  472.     sub    ah,GRAPH_PAGE_2     ; Subtract off the starting value
  473.     shl    ax,1            ; Move macro/slice number to AH register
  474.     xor    bh,bh            ; Setup to index through video tables
  475.     mov    bl,al            ; Convert offset into table index
  476.     mov    si,cs:[bx+CGA_Address]    ; Get the graphics offset table value
  477.     inc    si            ; Increment for screen hole check
  478.     js    Graph_Exit_2        ; Jump if this is a screen hole
  479.     mov    bl,ah            ; Get macro/slice number to BL register
  480.     shl    bx,1            ; Convert macro/slice into table index
  481.     add    si,cs:[bx+CGA_Slice]    ; Compute the actual screen address
  482.     mov    ch,cs:[di+CGA_Shift]    ; Get the word/byte shift values
  483.     mov    bl,cs:[bp+Reverse_Table]; Lookup the reverse bit value
  484.     shl    di,1            ; Convert address into table index
  485.     add    bx,cs:[di+Column_Table] ; Compute the actual table entry address
  486.     mov    dx,Word Ptr cs:[bx]    ; Get the expanded bit value (14 Bits)
  487.     mov    bx,dx            ; Get a copy of expanded bit value
  488.     mov    ax,WORD_MASK        ; Get the word mask value
  489.     xor    cl,cl            ; Setup for word shift count
  490.     rol    cx,4            ; Shift word shift count into CL
  491.     shr    ax,cl            ; Shift mask value into position
  492.     shr    bx,cl            ; Shift data value into position
  493.     not    ax            ; Invert the mask polarity
  494.     xchg    al,ah            ; Put mask bytes into the correct order
  495.     xchg    bl,bh            ; Put data bytes into the correct order
  496.     and    ax,Word Ptr es:[si]    ; Mask off all but desired bits
  497.     or    ax,bx            ; Logically OR in the new data bits
  498.     mov    Word Ptr es:[si],ax    ; Update the screen data word value
  499.     xor    cl,cl            ; Setup for byte shift count
  500.     rol    cx,4            ; Shift byte shift count into CL
  501.     or    cl,cl            ; Check for byte value required
  502.     jz    Graph_Exit_2        ; Jump if byte value NOT required
  503.     mov    al,BYTE_MASK        ; Get the byte mask value
  504.     shl    al,cl            ; Shift mask value into position
  505.     shl    dl,cl            ; Shift data value into position
  506.     not    al            ; Invert the mask polarity
  507.     and    al,Byte Ptr es:[si+BYTE_OFFSET]
  508.     or    al,dl            ; Logically OR in the new data bits
  509.     mov    Byte Ptr es:[si+BYTE_OFFSET],al
  510. Graph_Exit_2:
  511.     Restore bx,cx,dx,si        ; Restore the required registers
  512. Graph_Done_2:
  513.     ret                ; Return to the caller
  514. CGA_Graph_2    Endp            ; End of the CGA_Graph_2 procedure
  515.     Subttl    CGA_Text_Off    Text Off Routine (Graphics)
  516.     Page    +
  517. ;******************************************************************************
  518. ;
  519. ;    CGA_Text_Off(RAM_Space, Video_Segment)
  520. ;
  521. ;        If currently in a text mode
  522. ;            Reset the text mode flag bit (Graphics)
  523. ;            If in high resolution graphics mode
  524. ;                Set graphics mode 4 (320 x 200)
  525. ;            Endif
  526. ;            Call routine to enable intensity (No blink)
  527. ;            Call routine to restore graphics screen
  528. ;        Endif
  529. ;        Return to the caller
  530. ;
  531. ;    Registers on Entry:
  532. ;
  533. ;        DS    - 65C02 RAM space
  534. ;        ES    - Video memory segment
  535. ;
  536. ;    Registers on Exit:
  537. ;
  538. ;        AX    - Destroyed
  539. ;        BP    - Destroyed
  540. ;
  541. ;******************************************************************************
  542.         Even            ; Force procedure to even address
  543. CGA_Text_Off    Proc    Near        ; Text off (Graphics) procedure
  544.     test    cs:[Video_Flag],VIDEO_MODE
  545.     jnz    Text_Off_Done        ; Jump if this is NOT a text mode
  546.     or    cs:[Video_Flag],VIDEO_MODE
  547.     and    cs:[Video_Flag],Not VIDEO_INV
  548.     test    cs:[Video_Flag],RESOLUTION
  549.     jz    Do_Graphic        ; Jump if low resolution graphics
  550.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  551.     mov    al,GRAPH_MODE        ; Get the 320x200 graphics mode value
  552.     int    VIDEO            ; Set video mode to 320x200 graphics
  553. Do_Graphic:
  554.     call    Blink_Off        ; Call routine to turn blink off
  555.     call    Graphic_Restore     ; Call routine to restore graphics
  556. Text_Off_Done:
  557.     ret                ; Return to the caller
  558. CGA_Text_Off    Endp            ; End of the CGA_Text_Off procedure
  559.     Subttl    CGA_Text_On    Text On Routine (Text)
  560.     Page    +
  561. ;******************************************************************************
  562. ;
  563. ;    CGA_Text_On(RAM_Space, Video_Segment)
  564. ;
  565. ;        If currently in a graphics mode
  566. ;            Reset the graphics mode flag bit (Text)
  567. ;            If in high resolution graphics mode
  568. ;                Set text mode 0 (40x25)
  569. ;                Call routine to turn off cursor
  570. ;            Endif
  571. ;            Call routine to enable blink (No intensity)
  572. ;            Call routine to restore text screen
  573. ;        Endif
  574. ;        Return to the caller
  575. ;
  576. ;    Registers on Entry:
  577. ;
  578. ;        DS    - 65C02 RAM space
  579. ;        ES    - Video memory segment
  580. ;
  581. ;    Registers on Exit:
  582. ;
  583. ;        AX    - Destroyed
  584. ;        BP    - Destroyed
  585. ;
  586. ;******************************************************************************
  587.         Even            ; Force procedure to even address
  588. CGA_Text_On    Proc    Near        ; Text on (Text) procedure
  589.     test    cs:[Video_Flag],VIDEO_MODE
  590.     jz    Text_On_Done        ; Jump if this is a text mode
  591.     and    cs:[Video_Flag],Not VIDEO_MODE
  592.     or    cs:[Video_Flag],VIDEO_INV
  593.     test    cs:[Video_Flag],RESOLUTION
  594.     jz    Do_Text         ; Jump if low resolution graphics
  595.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  596.     mov    al,TEXT_MODE        ; Get the 40x25 text mode value
  597.     int    VIDEO            ; Set video mode to 40x25 text mode
  598.     call    Cursor_Off        ; Call routine to turn cursor off
  599. Do_Text:
  600.     call    Blink_On        ; Call routine to turn blink on
  601.     call    Text_Restore        ; Call routine to restore text
  602. Text_On_Done:
  603.     ret                ; Return to the caller
  604. CGA_Text_On    Endp            ; End of the CGA_Text_On procedure
  605.     Subttl    CGA_Mixed_Off    Mixed Off Routine (Text/Graphics)
  606.     Page    +
  607. ;******************************************************************************
  608. ;
  609. ;    CGA_Mixed_Off()
  610. ;
  611. ;        If this is mixed mode
  612. ;            Reset mixed mode flag bit
  613. ;            If this is a graphics mode
  614. ;                Call routine to restore graphics screen
  615. ;            Endif
  616. ;        Endif this is mixed mode
  617. ;        Return to the caller
  618. ;
  619. ;    Registers on Entry:
  620. ;
  621. ;        None
  622. ;
  623. ;    Registers on Exit:
  624. ;
  625. ;        AX    - Destroyed
  626. ;
  627. ;******************************************************************************
  628.         Even            ; Force procedure to even address
  629. CGA_Mixed_Off    Proc    Near        ; Mixed off (Text/Graphics) procedure
  630.     mov    al,cs:[Video_Flag]    ; Get the video flag word
  631.     test    al,MIXED_MODE        ; Check for mixed mode already selected
  632.     jz    Mixed_On_Done        ; Jump if this IS mixed mode already
  633.     and    cs:[Video_Flag],Not MIXED_MODE
  634.     or    cs:[Video_Flag],MIXED_INV
  635.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  636.     jz    Mixed_Off_Done        ; Jump if this is NOT a graphics mode
  637.     call    Graphic_Restore     ; Call routine to restore graphics
  638. Mixed_Off_Done:
  639.     ret                ; Return to the caller
  640. CGA_Mixed_Off    Endp            ; End of the CGA_Mixed_Off procedure
  641.     Subttl    CGA_Mixed_On    Mixed On Routine (Text & Graphics)
  642.     Page    +
  643. ;******************************************************************************
  644. ;
  645. ;    CGA_Mixed_On()
  646. ;
  647. ;        If this is NOT mixed mode
  648. ;            Set mixed mode flag bit
  649. ;            If this is a graphics mode
  650. ;                Call routine to update mixed screen
  651. ;            Endif
  652. ;        Endif this is NOT mixed mode
  653. ;        Return to the caller
  654. ;
  655. ;    Registers on Entry:
  656. ;
  657. ;        None
  658. ;
  659. ;    Registers on Exit:
  660. ;
  661. ;        AX    - Destroyed
  662. ;
  663. ;******************************************************************************
  664.         Even            ; Force procedure to even address
  665. CGA_Mixed_On    Proc    Near        ; Mixed on (Text & Graphics) procedure
  666.     mov    al,cs:[Video_Flag]    ; Get the video flag word
  667.     test    al,MIXED_MODE        ; Check for mixed mode already selected
  668.     jnz    Mixed_On_Done        ; Jump if this IS mixed mode already
  669.     or    cs:[Video_Flag],MIXED_MODE
  670.     and    cs:[Video_Flag],Not MIXED_INV
  671.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  672.     jz    Mixed_On_Done        ; Jump if this is NOT a graphics mode
  673.     call    Mixed_Update        ; Call routine to update mixed screen
  674. Mixed_On_Done:
  675.     ret                ; Return to the caller
  676. CGA_Mixed_On    Endp            ; End of the CGA_Mixed_On procedure
  677.     Subttl    CGA_Page_1    Select Page 1 Routine
  678.     Page    +
  679. ;******************************************************************************
  680. ;
  681. ;    CGA_Page_1(RAM_Space, Video_Segment)
  682. ;
  683. ;        If this is NOT page 1
  684. ;            Reset page number flag bit (Page 1)
  685. ;            If this is a text mode
  686. ;                Call routine to restore text screen
  687. ;            Else this is a graphics mode
  688. ;                Call routine to restore graphics screen
  689. ;            Endif
  690. ;        Endif this is NOT page 1
  691. ;        Return to the caller
  692. ;
  693. ;    Registers on Entry:
  694. ;
  695. ;        DS    - 65C02 RAM space
  696. ;        ES    - Video memory segment
  697. ;
  698. ;    Registers on Exit:
  699. ;
  700. ;        AX    - Destroyed
  701. ;        BP    - Destroyed
  702. ;
  703. ;******************************************************************************
  704.         Even            ; Force procedure to even address
  705. CGA_Page_1    Proc    Near        ; Select video page 1 procedure
  706.     mov    al,cs:[Video_Flag]    ; Get the video flag word
  707.     test    al,PAGE_NUMBER        ; Check for page 1 already selected
  708.     jz    Page_1_Done        ; Jump if this IS page 1 already
  709.     and    cs:[Video_Flag],Not PAGE_NUMBER
  710.     or    cs:[Video_Flag],PAGE_INV
  711.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  712.     jnz    Graphics_1        ; Jump if this is a graphics mode
  713.     call    Text_Restore        ; Call routine to restore text screen
  714.     jmp    Short Page_1_Done    ; Go return to the caller
  715. Graphics_1:
  716.     call    Graphic_Restore     ; Call routine to restore graphics
  717. Page_1_Done:
  718.     ret                ; Return to the caller
  719. CGA_Page_1    Endp            ; End of the CGA_Page_1 procedure
  720.     Subttl    CGA_Page_2    Select Page 2 Routine
  721.     Page    +
  722. ;******************************************************************************
  723. ;
  724. ;    CGA_Page_2(RAM_Space, Video_Segment)
  725. ;
  726. ;        If this is NOT page 2
  727. ;            Set page number flag bit (Page 2)
  728. ;            If this is a text mode
  729. ;                Call routine to restore text screen
  730. ;            Else this is a graphics mode
  731. ;                Call routine to restore graphics screen
  732. ;            Endif
  733. ;        Endif this is NOT page 2
  734. ;        Return to the caller
  735. ;
  736. ;    Registers on Entry:
  737. ;
  738. ;        DS    - 65C02 RAM space
  739. ;        ES    - Video memory segment
  740. ;
  741. ;    Registers on Exit:
  742. ;
  743. ;        AX    - Destroyed
  744. ;        BP    - Destroyed
  745. ;
  746. ;******************************************************************************
  747.         Even            ; Force procedure to even address
  748. CGA_Page_2    Proc    Near        ; Select video page 2 procedure
  749.     mov    al,cs:[Video_Flag]    ; Get the video flag word
  750.     test    al,PAGE_NUMBER        ; Check for page 2 already selected
  751.     jnz    Page_2_Done        ; Jump if this IS page 2 already
  752.     or    cs:[Video_Flag],PAGE_NUMBER
  753.     and    cs:[Video_Flag],Not PAGE_INV
  754.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  755.     jnz    Graphics_2        ; Jump if this is a graphics mode
  756.     call    Text_Restore        ; Call routine to restore text screen
  757.     jmp    Short Page_2_Done    ; Go return to the caller
  758. Graphics_2:
  759.     call    Graphic_Restore     ; Call routine to restore graphics
  760. Page_2_Done:
  761.     ret                ; Return to the caller
  762. CGA_Page_2    Endp            ; End of the CGA_Page_2 procedure
  763.     Subttl    CGA_Low_Res    Select Low Resolution Routine
  764.     Page    +
  765. ;******************************************************************************
  766. ;
  767. ;    CGA_Low_Res()
  768. ;
  769. ;        If this is NOT low resolution mode
  770. ;            Set low resolution mode flag bit
  771. ;            If this is a graphics mode
  772. ;                Set text mode 0 (40x25)
  773. ;                Call routine to turn off cursor
  774. ;                Call routine to enable intensity (No blink)
  775. ;                Call routine to restore graphics
  776. ;            Endif
  777. ;        Endif this is NOT low resolution mode
  778. ;        Return to the caller
  779. ;
  780. ;    Registers on Entry:
  781. ;
  782. ;        None
  783. ;
  784. ;    Registers on Exit:
  785. ;
  786. ;        AX    - Destroyed
  787. ;
  788. ;******************************************************************************
  789.         Even            ; Force procedure to even address
  790. CGA_Low_Res    Proc    Near        ; Select low resolution procedure
  791.     mov    al,cs:[Video_Flag]    ; Get the video flag byte
  792.     test    al,RESOLUTION        ; Check for low resolution mode
  793.     jz    Low_Res_Done        ; Jump if this IS low resolution
  794.     and    cs:[Video_Flag],Not RESOLUTION
  795.     or    cs:[Video_Flag],RES_INV
  796.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  797.     jz    Low_Res_Done        ; Jump if this is NOT a graphics mode
  798.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  799.     mov    al,TEXT_MODE        ; Get the 40x25 text mode value
  800.     int    VIDEO            ; Set video mode to 40x25 text mode
  801.     call    Cursor_Off        ; Call routine to turn cursor off
  802.     call    Blink_Off        ; Call routine to turn blink off
  803.     call    Graphic_Restore     ; Call routine to restore graphics
  804. Low_Res_Done:
  805.     ret                ; Return to the caller
  806. CGA_Low_Res    Endp            ; End of the CGA_Low_Res procedure
  807.     Subttl    CGA_High_Res    Select High Resolution Routine
  808.     Page    +
  809. ;******************************************************************************
  810. ;
  811. ;    CGA_High_Res()
  812. ;
  813. ;        If this is NOT high resolution mode
  814. ;            Set high resolution mode flag bit
  815. ;            If this is a graphics mode
  816. ;                Set graphics mode 4 (320 x 200)
  817. ;                Call routine to restore graphics
  818. ;            Endif
  819. ;        Endif this is NOT high resolution mode
  820. ;        Return to the caller
  821. ;
  822. ;    Registers on Entry:
  823. ;
  824. ;        None
  825. ;
  826. ;    Registers on Exit:
  827. ;
  828. ;        AX    - Destroyed
  829. ;
  830. ;******************************************************************************
  831.         Even            ; Force procedure to even address
  832. CGA_High_Res    Proc    Near        ; Select high resolution procedure
  833.     mov    al,cs:[Video_Flag]    ; Get the video flag byte
  834.     test    al,RESOLUTION        ; Check for high resolution mode
  835.     jnz    High_Res_Done        ; Jump if this IS high resolution
  836.     or    cs:[Video_Flag],RESOLUTION
  837.     and    cs:[Video_Flag],Not RES_INV
  838.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  839.     jz    High_Res_Done        ; Jump if this is NOT a graphics mode
  840.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  841.     mov    al,GRAPH_MODE        ; Get the 320x200 graphics mode value
  842.     int    VIDEO            ; Set video mode to 320x200 graphics
  843.     call    Graphic_Restore     ; Call routine to restore graphics
  844. High_Res_Done:
  845.     ret                ; Return to the caller
  846. CGA_High_Res    Endp            ; End of the CGA_High_Res procedure
  847.     Subttl    Text_Restore    Restore Text Screen Routine
  848.     Page    +
  849. ;******************************************************************************
  850. ;
  851. ;    Text_Restore(RAM_Space, Video_Segment)
  852. ;
  853. ;        Save the required registers
  854. ;        Set source index to page 1 memory (0400h)
  855. ;        If page 2 is selected
  856. ;            Set source index to page 2 memory (0800h)
  857. ;        Endif
  858. ;        Set destination index to video memory (BASE_ADDRESS)
  859. ;        Call routine to restore the text memory
  860. ;        Setup base address to video memory (BASE_ADDRESS)
  861. ;        Call routine to set base video address
  862. ;        Restore the required registers
  863. ;        Return to the caller
  864. ;
  865. ;    Registers on Entry:
  866. ;
  867. ;        DS    - 65C02 RAM space
  868. ;        ES    - Video memory segment
  869. ;
  870. ;    Registers on Exit:
  871. ;
  872. ;        AX    - Destroyed
  873. ;        BP    - Destroyed
  874. ;
  875. ;******************************************************************************
  876.         Even            ; Force procedure to even address
  877. Text_Restore    Proc    Near        ; Restore text screen procedure
  878.     Save    bx,cx,dx,si,di        ; Save the required registers
  879.     mov    si,TEXT_ADDRESS_1    ; Setup source index for page 1
  880.     test    cs:[Video_Flag],PAGE_NUMBER
  881.     jz    Do_Restore        ; Jump if this really is page 1
  882.     mov    si,TEXT_ADDRESS_2    ; Setup base address for page 2
  883. Do_Restore:
  884.     mov    di,BASE_ADDRESS     ; Setup destination index
  885.     mov    bp,TEXT_MASK        ; Setup destination mask value
  886.     call    Restore_Text        ; Call routine to restore text page 1
  887. Text_Set:
  888.     mov    bp,BASE_ADDRESS Shr 1    ; Setup base video address
  889.     call    Set_Address        ; Call routine to set base address
  890.     Restore bx,cx,dx,si,di        ; Restore the required registers
  891.     ret                ; Return to the caller
  892. Text_Restore    Endp            ; End of the Text_Restore procedure
  893.     Subttl    Restore_Text    Restore Text Memory Routine
  894.     Page    +
  895. ;******************************************************************************
  896. ;
  897. ;    Restore_Text(RAM_Space, Video_Segment, Source, Destination, Mask)
  898. ;
  899. ;        Set Macro_Counter to 8 (Restore 8 macro lines [24 rows])
  900. ;        While Macro_Counter > 0
  901. ;            Set Row_Counter to 3 (Restore 3 rows)
  902. ;            While Row_Counter > 0
  903. ;                Set Character_Counter to 40 (Restore 40 columns)
  904. ;                While Character_Counter > 0
  905. ;                    Load a character code from memory
  906. ;                    Lookup the character/attribute value
  907. ;                    Store character/attribute to memory
  908. ;                    Decrement the Character_Counter
  909. ;                Endwhile for Character_Count
  910. ;                Increment destination index by ROW_OFFSET (8)
  911. ;                Mask off all but valid destination address bits
  912. ;            Endwhile for Row_Counter
  913. ;            Increment source index by MACRO_OFFSET (8)
  914. ;        Endwhile for Macro_Counter
  915. ;        Return to the caller
  916. ;
  917. ;    Registers on Entry:
  918. ;
  919. ;        DS:SI - 65C02 RAM space source index
  920. ;        ES:DI - Video memory segment destination index
  921. ;        BP    - Destination index address mask
  922. ;
  923. ;    Registers on Exit:
  924. ;
  925. ;        AX-DX - Destroyed
  926. ;
  927. ;******************************************************************************
  928.         Even            ; Force procedure to even address
  929. Restore_Text    Proc    Near        ; Restore text memory procedure
  930.     mov    dh,MACRO_COUNT        ; Setup the macro count (8 = 24 Rows)
  931. Macro_Loop:
  932.     mov    dl,ROW_COUNT        ; Setup the row count (3 Rows)
  933.     Save    di            ; Save the destination index value
  934. Row_Loop:
  935.     mov    cx,CHAR_COUNT        ; Setup the character count (40 Columns)
  936. Char_Loop:
  937.     lodsb                ; Load the character code from memory
  938.     xor    ah,ah            ; Convert character code to full word
  939.     shl    ax,1            ; Convert character code to table index
  940.     mov    bx,ax            ; Setup to translate the character
  941.     mov    ax,cs:[bx + Char_Table] ; Lookup the correct character value
  942.     stosw                ; Store the character code to memory
  943.     loop    Char_Loop        ; Loop till all columns are moved
  944.     add    di,ROW_OFFSET        ; Increment destination address value
  945.     and    di,bp            ; Mask off all but valid address bits
  946.     dec    dl            ; Decrement the row counter value
  947.     jnz    Row_Loop        ; Jump if more rows to move
  948.     add    si,MACRO_OFFSET     ; Increment source address value
  949.     Restore di            ; Restore the destination index value
  950.     add    di,NEXT_OFFSET        ; Increment destination address value
  951.     dec    dh            ; Decrement the macro counter value
  952.     jnz    Macro_Loop        ; Jump if more macro lines to moves
  953.     ret                ; Return to the caller
  954. Restore_Text    Endp            ; End of the Restore_Text procedure
  955.     Subttl    Graphic_Restore Restore Graphic Screen Routine
  956.     Page    +
  957. ;******************************************************************************
  958. ;
  959. ;    Graphic_Restore(RAM_Space, Video_Segment)
  960. ;
  961. ;        Save the required registers
  962. ;        If in low resolution graphics mode
  963. ;            Set source index to page 1 memory (0400h)
  964. ;            If page 2 is selected
  965. ;                Set source index to page 2 memory (0800h)
  966. ;            Endif
  967. ;            Call routine to restore low resolution memory
  968. ;        Else in high resolution graphics mode
  969. ;            Set source index to page 1 memory (2000h)
  970. ;            If page 2 is selected
  971. ;                Set source index to page 2 memory (4000h)
  972. ;            Endif
  973. ;            Set destination index to video memory (BASE_ADDRESS)
  974. ;            Call routine to restore high resolution memory
  975. ;        Endif for type of graphics mode
  976. ;        Setup base address to video memory (BASE_ADDRESS)
  977. ;        Call routine to set base video address
  978. ;        Restore the required registers
  979. ;        Return to the caller
  980. ;
  981. ;    Registers on Entry:
  982. ;
  983. ;        DS    - 65C02 RAM space
  984. ;        ES    - Video memory segment
  985. ;
  986. ;    Registers on Exit:
  987. ;
  988. ;        AX    - Destroyed
  989. ;        BP    - Destroyed
  990. ;
  991. ;******************************************************************************
  992.         Even            ; Force procedure to even address
  993. Graphic_Restore Proc    Near        ; Restore graphic screen procedure
  994.     Save    bx,cx,dx,si,di        ; Save the required registers
  995.     test    cs:[Video_Flag],RESOLUTION
  996.     jz    Low_Restore        ; Jump if this is low resolution
  997. High_Restore:
  998.     mov    si,GRAPH_ADDRESS_1    ; Setup source index for page 1
  999.     test    cs:[Video_Flag],PAGE_NUMBER
  1000.     jz    Do_High         ; Jump if this really is page 1
  1001.     mov    si,GRAPH_ADDRESS_2    ; Setup base address for page 2
  1002. Do_High:
  1003.     mov    di,BASE_ADDRESS     ; Setup destination index
  1004.     call    Restore_High        ; Call routine to restore high res.
  1005.     jmp    Short Graphic_Set    ; Go setup the base address value
  1006. Low_Restore:
  1007.     mov    si,TEXT_ADDRESS_1    ; Setup source index for page 1
  1008.     test    cs:[Video_Flag],PAGE_NUMBER
  1009.     jz    Do_Low            ; Jump if this really is page 1
  1010.     mov    si,TEXT_ADDRESS_2    ; Setup base address for page 2
  1011. Do_Low:
  1012.     mov    di,BASE_ADDRESS     ; Setup destination index
  1013.     mov    bp,TEXT_MASK        ; Setup destination mask value
  1014.     call    Restore_Low        ; Call routine to restore low page 1
  1015. Graphic_Set:
  1016.     mov    bp,BASE_ADDRESS     ; Get base video address
  1017.     call    Set_Address        ; Call routine to set base address
  1018. Graphic_Done:
  1019.     Restore bx,cx,dx,si,di        ; Restore the required registers
  1020.     ret                ; Return to the caller
  1021. Graphic_Restore Endp            ; End of the Graphic_Restore procedure
  1022.     Subttl    Restore_Low    Restore Low Resolution Memory Routine
  1023.     Page    +
  1024. ;******************************************************************************
  1025. ;
  1026. ;    Restore_Low(RAM_Space, Video_Segment, Source, Destination, Mask)
  1027. ;
  1028. ;        Set Macro_Counter to 8 (Restore 8 macro lines [24 rows])
  1029. ;        While Macro_Counter > 0
  1030. ;            Set Row_Counter to 3 (Restore 3 rows)
  1031. ;            While Row_Counter > 0
  1032. ;                Set Character_Counter to 40 (Restore 40 columns)
  1033. ;                While Character_Counter > 0
  1034. ;                    Load a graphics byte from memory
  1035. ;                    Force character code to half block value
  1036. ;                    Store character/attribute to memory
  1037. ;                    Decrement the Character_Counter
  1038. ;                Endwhile for Character_Count
  1039. ;                Increment destination index by ROW_OFFSET (8)
  1040. ;                Mask off all but valid destination address bits
  1041. ;            Endwhile for Row_Counter
  1042. ;            Increment source index by MACRO_OFFSET (8)
  1043. ;        Endwhile for Macro_Counter
  1044. ;        Return to the caller
  1045. ;
  1046. ;    Registers on Entry:
  1047. ;
  1048. ;        DS:SI - 65C02 RAM space source index
  1049. ;        ES:DI - Video memory segment destination index
  1050. ;        BP    - Destination index address mask
  1051. ;
  1052. ;    Registers on Exit:
  1053. ;
  1054. ;        AX-DX - Destroyed
  1055. ;
  1056. ;******************************************************************************
  1057.         Even            ; Force procedure to even address
  1058. Restore_Low    Proc    Near        ; Restore low res. memory procedure
  1059.     mov    dh,MACRO_COUNT        ; Setup the macro count (8 = 24 Rows)
  1060. Loop_Macro:
  1061.     mov    dl,ROW_COUNT        ; Setup the row count (3 Rows)
  1062.     Save    di            ; Save the destination index value
  1063. Loop_Row:
  1064.     mov    cx,CHAR_COUNT        ; Setup the character count (40 Columns)
  1065. Loop_Byte:
  1066.     lodsb                ; Load the graphics byte from memory
  1067.     xor    ah,ah            ; Convert graphics byte to table index
  1068.     mov    bx,ax            ; Setup to translate the color
  1069.     mov    ah,cs:[bx + Map_Table]    ; Lookup the correct color value
  1070.     mov    al,BLOCK_CHAR        ; Force block character code value
  1071.     stosw                ; Store the character code to memory
  1072.     loop    Loop_Byte        ; Loop till all columns are moved
  1073.     add    di,ROW_OFFSET        ; Increment destination address value
  1074.     and    di,bp            ; Mask off all but valid address bits
  1075.     dec    dl            ; Decrement the row counter value
  1076.     jnz    Loop_Row        ; Jump if more rows to move
  1077.     add    si,MACRO_OFFSET     ; Increment source address value
  1078.     Restore di            ; Restore the destination index value
  1079.     add    di,NEXT_OFFSET        ; Increment destination address value
  1080.     dec    dh            ; Decrement the macro counter value
  1081.     jnz    Loop_Macro        ; Jump if more macro lines to moves
  1082.     ret                ; Return to the caller
  1083. Restore_Low    Endp            ; End of the Restore_Low procedure
  1084.     Subttl    Restore_High    Restore High Resolution Memory Routine
  1085.     Page    +
  1086. ;******************************************************************************
  1087. ;
  1088. ;    Restore_High(RAM_Space, Video_Segment, Source, Destination)
  1089. ;
  1090. ;        Set Slice_Counter to 8 (Restore 8 slices [192 lines])
  1091. ;        While Slice_Counter > 0
  1092. ;            Set Macro_Counter to 8 (Restore 8 macro lines [24 rows])
  1093. ;            While Macro_Counter > 0
  1094. ;                Set Row_Counter to 3 (Restore 3 rows)
  1095. ;                While Row_Counter > 0
  1096. ;                    Set Byte_Counter to 10 (40 Bytes)
  1097. ;                    While Byte_Counter > 0
  1098. ;                        Get next graphics byte
  1099. ;                        Reverse the data bits
  1100. ;                        Expand data bits for even column
  1101. ;                        Save the first 8 expanded bits
  1102. ;                        Get next graphics byte
  1103. ;                        Reverse the data bits
  1104. ;                        Expand data bits for odd column
  1105. ;                        Combine last 6 bits with next 2
  1106. ;                        Save the next 16 expanded bits
  1107. ;                        Get next graphics byte
  1108. ;                        Reverse the data bits
  1109. ;                        Expand data bits for even column
  1110. ;                        Combine last 4 bits with next 4
  1111. ;                        Save the next 16 expanded bits
  1112. ;                        Get next graphics byte
  1113. ;                        Reverse the data bits
  1114. ;                        Expand data bits for odd column
  1115. ;                        Combine last 2 bits with next 14
  1116. ;                        Save the last 16 expanded bits
  1117. ;                    Endwhile for Byte_Count
  1118. ;                Increment destination index by NEXT_ROW (2490)
  1119. ;                Endwhile for Row_Counter
  1120. ;                Increment source index by NEXT_MACRO (320)
  1121. ;            Endwhile for Macro_Counter
  1122. ;            Toggle destination for odd/even scan line
  1123. ;            If moving to an even scan line
  1124. ;                Increment destination index by NEXT_OFFSET (80)
  1125. ;            Endif
  1126. ;        Endwhile for Slice_Counter
  1127. ;        Return to the caller
  1128. ;
  1129. ;    Registers on Entry:
  1130. ;
  1131. ;        DS:SI - 65C02 RAM space source index
  1132. ;        ES:DI - Video memory segment destination index
  1133. ;
  1134. ;    Registers on Exit:
  1135. ;
  1136. ;        AX-DX - Destroyed
  1137. ;
  1138. ;******************************************************************************
  1139.         Even            ; Force procedure to even address
  1140. Restore_High    Proc    Near        ; Restore high res. memory procedure
  1141.     mov    ch,SLICE_COUNT        ; Setup the slice count (8 = 192 Lines)
  1142. Slice_Next:
  1143.     mov    dh,MACRO_COUNT        ; Setup the macro count (8 = 24 Rows)
  1144.     Save    di            ; Save the destination index value
  1145. Macro_Next:
  1146.     mov    dl,ROW_COUNT        ; Setup the row count (3 Rows)
  1147.     Save    di            ; Save the destination index value
  1148. Row_Next:
  1149.     mov    cl,BYTE_COUNT        ; Setup graphics count (10 = 40 Bytes)
  1150. Byte_Next:
  1151.     lodsb                ; Get the next graphics data byte
  1152.     mov    bl,al            ; Move data byte into BL register
  1153.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1154.     mov    bl,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1155.     mov    bx,cs:[bx+Even_Table]    ; Expand data bits for an even column
  1156.     mov    al,bh            ; Get the first 8 expanded bits
  1157.     stosb                ; Store data bits to screen memory
  1158.     mov    ah,bl            ; Save the last 6 expanded bits
  1159.     lodsb                ; Get the next graphics data byte
  1160.     mov    bl,al            ; Move data byte into BL register
  1161.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1162.     mov    bl,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1163.     mov    bx,cs:[bx+Odd_Table]    ; Expand data bits for an odd column
  1164.     mov    al,bh            ; Get the first 8 expanded bits
  1165.     shr    al,6            ; Save only the first 2 expanded bits
  1166.     or    al,ah            ; Logically OR with other 6 bits
  1167.     shl    bx,2            ; Shift out first 2 expanded bits
  1168.     mov    ah,bh            ; Move next 8 expanded bits into AH
  1169.     stosw                ; Store data bits to screen memory
  1170.     mov    ah,bl            ; Save the last 4 expanded bits
  1171.     lodsb                ; Get the next graphics data byte
  1172.     mov    bl,al            ; Move data byte into BL register
  1173.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1174.     mov    bl,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1175.     mov    bx,cs:[bx+Even_Table]    ; Expand data bits for an even column
  1176.     mov    al,bh            ; Get the first 8 expanded bits
  1177.     shr    al,4            ; Save only the first 4 expanded bits
  1178.     or    al,ah            ; Logically OR with other 4 bits
  1179.     shl    bx,4            ; Shift out first 4 expanded bits
  1180.     mov    ah,bh            ; Move next 8 expanded bits into AH
  1181.     stosw                ; Store data bits to screen memory
  1182.     mov    ah,bl            ; Save the last 2 expanded bits
  1183.     lodsb                ; Get the next graphics data byte
  1184.     mov    bl,al            ; Move data byte into BL register
  1185.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1186.     mov    bl,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1187.     mov    bx,cs:[bx+Odd_Table]    ; Expand data bits for an odd column
  1188.     shr    bx,2            ; Shift data bits into position
  1189.     mov    al,bh            ; Move first 6 expanded bits into AL
  1190.     or    al,ah            ; Logically OR with other 2 bits
  1191.     mov    ah,bl            ; Move next 8 expanded bits into AH
  1192.     stosw                ; Store data bits to screen memory
  1193.     dec    cl            ; Decrement the graphics byte count
  1194.     jnz    Byte_Next        ; Jump if more bytes to move
  1195.     add    di,NEXT_ROW        ; Increment to the next graphics row
  1196.     dec    dl            ; Decrement the row counter
  1197.     jnz    Row_Next        ; Jump if more rows to move
  1198.     add    si,MACRO_OFFSET     ; Increment source address value
  1199.     Restore di            ; Restore the destination index value
  1200.     add    di,NEXT_MACRO        ; Increment to the next macro line
  1201.     dec    dh            ; Decrement the macro counter value
  1202.     jz    Macro_Done        ; Jump if all macro lines are moved
  1203.     jmp    Macro_Next        ; Go process more macro lines
  1204. Macro_Done:
  1205.     Restore di            ; Restore the destination index value
  1206.     xor    di,LINE_MASK        ; Adjust for the odd scan line offset
  1207.     test    di,LINE_MASK        ; Check for moving to an even scan line
  1208.     jnz    Skip_Inc        ; Jump if NOT moving to an even line
  1209.     add    di,NEXT_OFFSET        ; Adjust for moving to an even scan line
  1210. Skip_Inc:
  1211.     dec    ch            ; Decrement the slice counter value
  1212.     jz    Restore_Done        ; Jump if restore is complete
  1213.     jmp    Slice_Next        ; Go process more slice sets
  1214. Restore_Done:
  1215.     ret                ; Return to the caller
  1216. Restore_High    Endp            ; End of the Restore_High procedure
  1217.     Subttl    Mixed_Update    Mixed Mode Update Routine
  1218.     Page    +
  1219. ;******************************************************************************
  1220. ;
  1221. ;    Mixed_Update()
  1222. ;
  1223. ;
  1224. ;        Return to the caller
  1225. ;
  1226. ;    Registers on Entry:
  1227. ;
  1228. ;        None
  1229. ;
  1230. ;    Registers on Exit:
  1231. ;
  1232. ;        None
  1233. ;
  1234. ;******************************************************************************
  1235.         Even            ; Force procedure to even address
  1236. Mixed_Update    Proc    Near        ; Mixed screen update procedure
  1237.  
  1238.     ret                ; Return to the caller
  1239. Mixed_Update    Endp            ; End of the Mixed_Update procedure
  1240.     Subttl    CGA_Restore    Restore Screen Routine
  1241.     Page    +
  1242. ;******************************************************************************
  1243. ;
  1244. ;    CGA_Restore(Video_Segment)
  1245. ;
  1246. ;        If this is text mode
  1247. ;            Set text mode 0 (40x25)
  1248. ;            Call routine to turn off cursor
  1249. ;            Call routine to enable blink (No intensity)
  1250. ;            Call the text restore routine
  1251. ;        Else this is a graphics mode
  1252. ;            If this is high resolution graphics
  1253. ;                Set graphics mode 4 (320 x 200)
  1254. ;            Else this is low resolution graphics
  1255. ;                Set text mode 0 (40x25)
  1256. ;                Call routine to turn off cursor
  1257. ;                Call routine to enable intensity (No blink)
  1258. ;            Endif for graphics resolution
  1259. ;            Call the graphics restore routine
  1260. ;        Endif for video mode
  1261. ;        Return to the caller
  1262. ;
  1263. ;    Registers on Entry:
  1264. ;
  1265. ;        ES    - Video segment
  1266. ;
  1267. ;    Registers on Exit:
  1268. ;
  1269. ;        AX    - Destroyed
  1270. ;        BP    - Destroyed
  1271. ;
  1272. ;******************************************************************************
  1273.         Even            ; Force procedure to even address
  1274. CGA_Restore    Proc    Near        ; Restore screen procedure
  1275.     test    cs:[Video_Flag],VIDEO_MODE
  1276.     jnz    Mode_Graphics        ; Jump if this is a graphics mode
  1277. Mode_Text:
  1278.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  1279.     mov    al,TEXT_MODE        ; Get the 40x25 text mode value
  1280.     int    VIDEO            ; Set video mode to 40x25 text mode
  1281.     call    Cursor_Off        ; Call routine to turn cursor off
  1282.     call    Blink_On        ; Call routine to turn blink on
  1283.     call    Text_Restore        ; Call routine to restore text screen
  1284.     jmp    Short CGA_Done        ; Go return to the caller
  1285. Mode_Graphics:
  1286.     test    cs:[Video_Flag],RESOLUTION
  1287.     jnz    CGA_High
  1288. CGA_Low:
  1289.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  1290.     mov    al,TEXT_MODE        ; Get the 40x25 text mode value
  1291.     int    VIDEO            ; Set video mode to 40x25 text mode
  1292.     call    Cursor_Off        ; Call routine to turn cursor off
  1293.     call    Blink_Off        ; Call routine to turn blink off
  1294.     jmp    Short Do_CGA        ; Go continue the CGA restore
  1295. CGA_High:
  1296.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  1297.     mov    al,GRAPH_MODE        ; Get the 320x200 graphics mode value
  1298.     int    VIDEO            ; Set video mode to 320x200 graphics
  1299. Do_CGA:
  1300.     call    Graphic_Restore     ; Call graphics screen restore routine
  1301. CGA_Done:
  1302.     ret                ; Return to the caller
  1303. CGA_Restore    Endp            ; End of the CGA_Restore procedure
  1304. ;******************************************************************************
  1305. ;
  1306. ;    Define the end of the Emulator Code Segment
  1307. ;
  1308. ;******************************************************************************
  1309. Emulate Ends
  1310.     End                ; End of the CGA module
  1311.